package com.oa.jx.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.mdp.core.entity.Tips;
import com.mdp.core.err.BizException;
import com.mdp.core.service.BaseService;
import com.mdp.core.utils.NumberUtil;
import com.mdp.safe.client.entity.User;
import com.oa.common.entity.UserBaseInfo;
import com.oa.common.service.UserBaseInfoService; 
import com.oa.jx.entity.JxAssessClass;
import com.oa.jx.entity.JxAssessGrade;
import com.oa.jx.entity.JxAssessGradeDetail;
import com.oa.jx.mapper.JxAssessGradeMapper;
import com.oa.jx.vo.BatchGradeVo;
import com.oa.jx.vo.JxAssessInfoVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author maimeng-mdp code-gen
 * @since 2023年10月9日
 */
@Service
public class JxAssessGradeService extends BaseService<JxAssessGradeMapper, JxAssessGrade> {
    static Logger logger = LoggerFactory.getLogger(JxAssessGradeService.class);

    /**
     * 自定义查询，支持多表关联
     *
     * @param page 分页条件
     * @param ew   一定要，并且必须加@Param("ew")注解
     * @param ext  如果xml中需要根据某些值进行特殊处理，可以通过这个进行传递，非必须，注解也可以不加
     * @return
     */
    public List<Map<String, Object>> selectListMapByWhere(IPage page, QueryWrapper ew, Map<String, Object> ext) {
        return baseMapper.selectListMapByWhere(page, ew, ext);
    }

    @Autowired
    JxAssessGradeDetailService jxAssessGradeDetailService;
    @Autowired
    JxAssessClassService jxAssessClassService;

    @Autowired
    UserBaseInfoService hrUserBaseInfoService;

    /** 请在此类添加自定义函数 */

    /**
     * 考核状态
     * 0-初始
     * 1-待员工确认
     * 2-待主管确认
     * 3-已确认-待自评
     * 4-已自评-待复评
     * 5-已复评-待核定
     * 6-已核定
     * 7-已完成
     * <p>
     * selfConfirm-员工确认->待主管确认
     * reConfirm-主管确认->待自评
     * rejectReConfirm-主管拒绝，待员工重新确认
     * selfEvalConfirm-自评提交->待复评
     * reEvalConfirm-复评提交->待核定
     * vouchEvalConfirm-核定提交->已核定
     *
     * @param jxAssessInfoVo
     */
    @Transactional
    public void saveAssessInfo(JxAssessInfoVo jxAssessInfoVo, JxAssessGrade jxAssessGradeDb) {
        JxAssessGrade jxAssessGrade = new JxAssessGrade();
        BeanUtils.copyProperties(jxAssessInfoVo, jxAssessGrade);
        if (jxAssessGradeDb == null) {
            this.initJxAssessGrade(jxAssessGrade);
        } else {
            jxAssessGrade.setId(jxAssessGradeDb.getId());
        }
        //保存分数详情
        List<JxAssessGradeDetail> jxAssessGradeDetails = new ArrayList<>();
        for (int i = 0; i < jxAssessInfoVo.getContents().size(); i++) {
            Map<String, Object> map = jxAssessInfoVo.getContents().get(i);
            //传过来的是整型，需要转化一下
            BigDecimal rePoints = NumberUtil.getBigDecimal(map.get("rePoints"), BigDecimal.ZERO);
            BigDecimal selfPoints = NumberUtil.getBigDecimal(map.get("selfPoints"), BigDecimal.ZERO);
            BigDecimal vouchPoints = NumberUtil.getBigDecimal(map.get("vouchPoints"), BigDecimal.ZERO);
            Integer seqNum = NumberUtil.getInteger(map.get("seqNum"), 0);
            JxAssessGradeDetail jxAssessGradeDetail = new JxAssessGradeDetail();
            jxAssessGradeDetail.setGradeId(jxAssessGrade.getId());
            jxAssessGradeDetail.setContentId((String) map.get("id"));
            jxAssessGradeDetail.setRePoints(rePoints);
            jxAssessGradeDetail.setSelfPoints(selfPoints);
            jxAssessGradeDetail.setVouchPoints(vouchPoints);
            jxAssessGradeDetail.setSelfDesc((String) map.get("selfDesc"));
            jxAssessGradeDetails.add(jxAssessGradeDetail);
        }
        //如果为null则是第一次打分
        if (jxAssessGradeDb != null) {
            jxAssessGrade = calcJxAssessGradeStatusByAction(jxAssessGrade, jxAssessGradeDb.getStatus(), jxAssessInfoVo.getAction());
            jxAssessGrade = this.calcJxAssessGradeFinalPoints(jxAssessGrade, jxAssessGradeDb, jxAssessGradeDetails, jxAssessInfoVo.getAction());
            jxAssessGrade = this.calcJxAssessGradeClassByFinalPoints(jxAssessGrade);
            jxAssessGrade = calcJxAssessReUserAndVouchUser(jxAssessGrade);
            this.updateByPk(jxAssessGrade);
            JxAssessGradeDetail jxAssessGradeDetail = new JxAssessGradeDetail();
            jxAssessGradeDetail.setGradeId(jxAssessGrade.getId());
            jxAssessGradeDetailService.deleteByWhere(jxAssessGradeDetail);
        } else {
            //通过方案执行编号、员工编号、期间唯一确定是否重复
            JxAssessGrade query = new JxAssessGrade();
            if ("0".equals(jxAssessGrade.getSchemeType())) {
                query.setMonth(jxAssessGrade.getMonth());
            } else if ("1".equals(jxAssessGrade.getSchemeType())) {
                query.setQuarter(jxAssessGrade.getQuarter());
            } else if ("2".equals(jxAssessGrade.getSchemeType())) {
                query.setSemiAnnual(jxAssessGrade.getSemiAnnual());
            } else if ("3".equals(jxAssessGrade.getSchemeType())) {
                query.setAnnual(jxAssessGrade.getAnnual());
            }
            query.setYear(jxAssessGrade.getYear());
            query.setAssUserid(jxAssessGrade.getAssUserid());
            query.setSchemeExecId(jxAssessGrade.getSchemeExecId());
            if (this.countByWhere(query) > 0) {
                throw new BizException("该绩效已存在，不能再添加");
            }
            ;
            jxAssessGrade = calcJxAssessGradeStatusByAction(jxAssessGrade, "0", jxAssessInfoVo.getAction());
            jxAssessGrade = calcJxAssessGradeFinalPoints(jxAssessGrade, jxAssessGradeDb, jxAssessGradeDetails, jxAssessInfoVo.getAction());
            jxAssessGrade = calcJxAssessGradeClassByFinalPoints(jxAssessGrade);
            jxAssessGrade = calcJxAssessReUserAndVouchUser(jxAssessGrade);
            this.insert(jxAssessGrade);
        }

        jxAssessGradeDetailService.batchInsert(jxAssessGradeDetails);
    }

    JxAssessGrade initJxAssessGrade(JxAssessGrade jxAssessGrade) {
        jxAssessGrade.setReCstatus("0");
        jxAssessGrade.setIsVouch("0");
        jxAssessGrade.setIsSelf("0");
        jxAssessGrade.setIsReEval("0");
        jxAssessGrade.setStatus("0");
        jxAssessGrade.setAssCstatus("0");
        jxAssessGrade.setVouchCstatus("0");
        jxAssessGrade.setRePoints(BigDecimal.ZERO);
        jxAssessGrade.setVouchPoints(BigDecimal.ZERO);
        jxAssessGrade.setSelfPoints(BigDecimal.ZERO);
        jxAssessGrade.setId(this.createKey("id"));
        return jxAssessGrade;
    }

    public JxAssessGrade calcJxAssessReUserAndVouchUser(JxAssessGrade jxAssessGrade) {
        if (!StringUtils.hasText(jxAssessGrade.getReUserid())) {
            UserBaseInfo userBaseInfoQuery = new UserBaseInfo();
            userBaseInfoQuery.setBranchId(jxAssessGrade.getBranchId());
            userBaseInfoQuery.setUserid(jxAssessGrade.getAssUserid());
            List<UserBaseInfo> hrUserBaseInfos = this.hrUserBaseInfoService.selectListByWhere(userBaseInfoQuery);
            if (hrUserBaseInfos != null && hrUserBaseInfos.size() > 0) {
                UserBaseInfo hrUserBaseInfo = hrUserBaseInfos.get(0);
                jxAssessGrade.setReUserid(hrUserBaseInfo.getReportId());
                jxAssessGrade.setReUsername(hrUserBaseInfo.getReportName());
                jxAssessGrade.setAssDeptid(hrUserBaseInfo.getDeptid());
                jxAssessGrade.setAssDeptName(hrUserBaseInfo.getDeptName());
                jxAssessGrade.setReCstatus("0");
                userBaseInfoQuery.setUserid(jxAssessGrade.getReUserid());
                hrUserBaseInfos = this.hrUserBaseInfoService.selectListByWhere(userBaseInfoQuery);
                if (hrUserBaseInfos != null && hrUserBaseInfos.size() > 0) {
                    UserBaseInfo hrUserBaseInfo2 = hrUserBaseInfos.get(0);
                    jxAssessGrade.setVouchId(hrUserBaseInfo2.getUserid());
                    jxAssessGrade.setVouchName(hrUserBaseInfo2.getUsername());
                }

            }

        }
        return jxAssessGrade;
    }

    public void batchOpenToConfirm(String schemeExecId) {
//        this.update("batchOpenToConfirm", schemeExecId);
        baseMapper.batchOpenToConfirm(schemeExecId);
    }

    public JxAssessGrade calcJxAssessGradeFinalPoints(JxAssessGrade jxAssessGradeNew, JxAssessGrade jxAssessGradeDb, List<JxAssessGradeDetail> details, String action) {
        BigDecimal finalPoints = BigDecimal.ZERO;

        for (JxAssessGradeDetail detail : details) {
            if ("selfEvalConfirm".equals(action)) {
                finalPoints = finalPoints.add(detail.getSelfPoints());
            } else if ("reEvalConfirm".equals(action)) {
                finalPoints = finalPoints.add(detail.getRePoints());
            } else if ("vouchEvalConfirm".equals(action)) {
                finalPoints = finalPoints.add(detail.getVouchPoints());
            } else if ("save".equals(action)) {
                if (jxAssessGradeDb != null) {
                    String oldStatus = jxAssessGradeDb.getStatus();
                    if ("3".equals(oldStatus)) {
                        finalPoints = finalPoints.add(detail.getSelfPoints());
                    } else if ("4".equals(oldStatus)) {
                        finalPoints = finalPoints.add(detail.getRePoints());
                    } else if ("5".equals(oldStatus)) {
                        finalPoints = finalPoints.add(detail.getVouchPoints());
                    } else {
                        finalPoints = jxAssessGradeDb.getFinalPoints();
                    }

                }

            } else {
                if (jxAssessGradeDb != null) {
                    finalPoints = jxAssessGradeDb.getFinalPoints();
                }
            }
        }
        jxAssessGradeNew.setFinalPoints(finalPoints);
        return jxAssessGradeNew;
    }

    public JxAssessGrade calcJxAssessGradeClassByFinalPoints(JxAssessGrade jxAssessGradeNew) {
        JxAssessClass jxAssessClass = this.jxAssessClassService.calcClassByFinalPoints(jxAssessGradeNew.getFinalPoints());
        if (jxAssessClass != null) {
            jxAssessGradeNew.setClassType(jxAssessClass.getClassType());
            jxAssessGradeNew.setClassTypeName(jxAssessClass.getName());
        }
        return jxAssessGradeNew;
    }

    public JxAssessGrade calcJxAssessGradeStatusByAction(JxAssessGrade jxAssessGradeNew, String oldStatus, String action) {
        String newStatus = "0";
        if ("save".equals(action)) {
            newStatus = oldStatus;
        } else if ("selfConfirm".equals(action)) {
            newStatus = "2";
            jxAssessGradeNew.setAssCstatus("1");
            jxAssessGradeNew.setAssCtime(new Date());
        } else if ("reConfirm".equals(action)) {
            newStatus = "3";
            jxAssessGradeNew.setReCstatus("1");
            jxAssessGradeNew.setReCtime(new Date());
        } else if ("rejectReConfirm".equals(action)) {
            newStatus = "1";
            jxAssessGradeNew.setAssCstatus("0");
        } else if ("selfEvalConfirm".equals(action)) {
            newStatus = "4";
            jxAssessGradeNew.setIsSelf("1");
            jxAssessGradeNew.setSelfTime(new Date());
        } else if ("reEvalConfirm".equals(action)) {
            newStatus = "5";
            jxAssessGradeNew.setIsReEval("1");
            jxAssessGradeNew.setReTime(new Date());
        } else if ("vouchEvalConfirm".equals(action)) {
            jxAssessGradeNew.setIsVouch("1");
            jxAssessGradeNew.setVouchTime(new Date());
            newStatus = "6";
        }
        jxAssessGradeNew.setStatus(newStatus);
        return jxAssessGradeNew;
    }

    /**
     * 考核状态
     * 0-初始
     * 1-待员工确认
     * 2-待主管确认
     * 3-已确认-待自评
     * 4-已自评-待复评
     * 5-已复评-待核定
     * 6-已核定
     * 7-已完成
     *
     * @param jxAssessGradeDb
     * @param action
     * @return
     */
    public Tips checkJxAssessGradeStatusByAction(JxAssessGrade jxAssessGradeDb, String action, User user) {
        Tips tips = new Tips("成功");
        if (jxAssessGradeDb == null) {
            if (!"save".equals(action)) {
                tips.setErrMsg("action-must-save", "当前只能进行数据保存");
            }
            return tips;
        }
        if ("save".equals(action)) {
            if ("1".equals(jxAssessGradeDb.getStatus())) {
                if (!user.getUserid().equals(jxAssessGradeDb.getAssUserid())) {
                    tips.setErrMsg("assUserid-not-right", "您不是考核人员，无权提交");
                }
            } else if ("2".equals(jxAssessGradeDb.getStatus())) {
                if (!user.getUserid().equals(jxAssessGradeDb.getReUserid())) {
                    tips.setErrMsg("reUserid-not-right", "您不是复评人员，无权提交");
                }
            } else if ("3".equals(jxAssessGradeDb.getStatus())) {
                if (!user.getUserid().equals(jxAssessGradeDb.getAssUserid())) {
                    tips.setErrMsg("assUserid-not-right", "您不是考核人员，无权提交");
                }
            } else if ("4".equals(jxAssessGradeDb.getStatus())) {
                if (!user.getUserid().equals(jxAssessGradeDb.getReUserid())) {
                    tips.setErrMsg("reUserid-not-right", "您不是复评人员，无权提交");
                }
            } else if ("5".equals(jxAssessGradeDb.getStatus())) {
                if (!user.getUserid().equals(jxAssessGradeDb.getVouchId())) {
                    tips.setErrMsg("vouchId-not-right", "您不是核定人员，无权提交");
                }
            }
            return tips;
        } else if ("selfConfirm".equals(action)) {
            if (!"1".equals(jxAssessGradeDb.getStatus())) {
                tips.setErrMsg("status-must-1", "当前不能进行员工确认");
            }
            if (!user.getUserid().equals(jxAssessGradeDb.getAssUserid())) {
                tips.setErrMsg("assUserid-not-right", "您不是考核人员，无权提交");
            }
            return tips;
        } else if ("reConfirm".equals(action)) {
            if (!"2".equals(jxAssessGradeDb.getStatus())) {
                tips.setErrMsg("status-must-2", "当前不能进行主管确认");
            }
            if (!user.getUserid().equals(jxAssessGradeDb.getReUserid())) {
                tips.setErrMsg("reUserid-not-right", "您不是复评人员，无权提交");
            }
            return tips;
        } else if ("rejectReConfirm".equals(action)) {
            if (!"2".equals(jxAssessGradeDb.getStatus())) {
                tips.setErrMsg("status-must-2", "当前不能进行主管拒绝");
            }
            if (!user.getUserid().equals(jxAssessGradeDb.getReUserid())) {
                tips.setErrMsg("reUserid-not-right", "您不是复评人员，无权提交");
            }
            return tips;
        } else if ("selfEvalConfirm".equals(action)) {
            if (!"3".equals(jxAssessGradeDb.getStatus())) {
                tips.setErrMsg("status-must-3", "当前不能进行自评");
            }

            if (!user.getUserid().equals(jxAssessGradeDb.getAssUserid())) {
                tips.setErrMsg("assUserid-not-right", "您不是考核人，无权提交");
            }
            return tips;
        } else if ("reEvalConfirm".equals(action)) {
            if (!"4".equals(jxAssessGradeDb.getStatus())) {
                tips.setErrMsg("status-must-4", "当前不能进行自评");
            }

            if (!user.getUserid().equals(jxAssessGradeDb.getReUserid())) {
                tips.setErrMsg("reUserid-not-right", "您不是复评人，无权提交");
            }
            return tips;
        } else if ("vouchEvalConfirm".equals(action)) {
            if (!"5".equals(jxAssessGradeDb.getStatus())) {
                tips.setErrMsg("status-must-5", "当前不能进行自评");
            }

            if (!user.getUserid().equals(jxAssessGradeDb.getVouchId())) {
                tips.setErrMsg("vouchId-not-right", "您不是核定人，无权提交");
            }
            return tips;
        }
        return tips;
    }

    public List<Map<String, Object>> selectUserAssessStatistics(Map<String, Object> jxAssessGrade) {
        return baseMapper.selectUserAssessStatistics(jxAssessGrade);
    }

    //获取当前部门里面的评优占比
    public Map<String, Object> getMakeUp(Map dept) {
        return map();
    }

    public Map<String, Object> getDeptAssessmentOf(Map<String, Object> map) {
        Map<String, Object> makeUp = getMakeUp(map);
        return makeUp;
    }

    public List<Map<String, Object>> selectDeptAssessStatistics(Map<String, Object> jxAssessGrade) {
        return baseMapper.selectDeptAssessStatistics(jxAssessGrade);
    }

    public void batchUpdateGrade(BatchGradeVo batchGradeVo) {
        baseMapper.batchUpdateGrade(batchGradeVo);
    }

    public void batchDelGrade(BatchGradeVo batchGradeVo) {
        baseMapper.batchDelGrade(batchGradeVo);
    }

    public List<Map<String, Object>> selectListNoReUseridOrNoVouchUserid(Map<String, Object> map) {
        return baseMapper.selectListNoReUseridOrNoVouchUserid(map);
    }
}

